home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / io-curses.c < prev    next >
C/C++ Source or Header  |  1993-05-22  |  22KB  |  1,259 lines

  1. /*    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7.  
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12.  
  13. You should have received a copy of the GNU General Public License
  14. along with this software; see the file COPYING.  If not, write to
  15. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17.  
  18. #include "proto.h"
  19. #include "funcdef.h"
  20. #include <stdio.h>
  21. #include <curses.h>
  22. #include <fcntl.h>
  23. #include <errno.h>
  24. #include <ctype.h>
  25. #include <signal.h>
  26. #undef NULL
  27. #include "sysdef.h"
  28. #include "global.h"
  29. #include "cell.h"
  30. #include "cmd.h"
  31. #include "line.h"
  32. #include "io-generic.h"
  33. #include "io-edit.h"
  34. #include "io-term.h"
  35. #include "io-abstract.h"
  36. #include "io-utils.h"
  37. #include "lists.h"
  38. #include "regions.h"
  39. #include "window.h"
  40. #include "key.h"
  41. #include "input.h"
  42. #include "info.h"
  43.  
  44. #define MIN_WIN_HEIGHT    (cwin->flags&WIN_EDGES ? 2 : 1)
  45. #define MIN_WIN_WIDTH    (cwin->flags&WIN_EDGES ? 6 : 1)
  46.  
  47. static int redrew = 0;
  48. static int textout = 0;
  49. static int term_cursor_claimed = 0;
  50.  
  51. #ifdef __STDC__
  52. static void move_cursor_to (struct window *, CELLREF, CELLREF, int);
  53. #else
  54. static void move_cursor_to ();
  55. #endif
  56.  
  57.  
  58. #ifdef __STDC__
  59. static int
  60. curses_metric (char * str, int len)
  61. #else
  62. static int
  63. curses_metric (str, len)
  64.      char * str;
  65.      int len;
  66. #endif
  67. {
  68.   return len;
  69. }
  70.  
  71. static struct input_view input_view
  72.   = {0, curses_metric, curses_metric, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  73.  
  74. #ifdef __STDC__
  75. static void
  76. _io_redraw_input (void)
  77. #else
  78. static void
  79. _io_redraw_input ()
  80. #endif
  81. {
  82.   int pos;
  83.   int row = (input_view.current_info ? 0 : input);
  84.  
  85.   if (input_view.info_redraw_needed)
  86.     {
  87.       input_view.info_redraw_needed = 0;
  88.       io_repaint ();
  89.       return;
  90.     }
  91.  
  92.   if (input_view.redraw_needed == NO_REDRAW)
  93.     return;
  94.  
  95.   if (input_view.redraw_needed == FULL_REDRAW)
  96.     {
  97.       /* Redraw    the prompt. */ 
  98.       move (row, 0);
  99.       if (input_view.expanded_keymap_prompt)
  100.     {
  101.       addstr (input_view.expanded_keymap_prompt);
  102.       clrtoeol ();
  103.       input_view.redraw_needed = NO_REDRAW;
  104.       return;
  105.     }
  106.       if (input_view.prompt_wid)
  107.     addstr (input_view.prompt);
  108.       pos = input_view.visibility_begin;
  109.     }
  110.   else
  111.     {
  112.       pos = input_view.redraw_needed;
  113.       move (row,
  114.         input_view.prompt_wid + pos - input_view.visibility_begin);
  115.     }
  116.     
  117.   if (   input_view.input_area
  118.       && (input_view.visibility_end >= input_view.visibility_begin)
  119.       && (input_view.visibility_begin < strlen (input_view.input_area->buf)))
  120.     {
  121.       int x;
  122.       for (x = pos; x <= input_view.visibility_end; ++x)
  123.     addch (input_view.input_area->buf[x]);
  124.     }
  125.   clrtoeol ();
  126.   input_view.redraw_needed = NO_REDRAW;
  127. }
  128.  
  129.  
  130. #undef MIN
  131. #define MIN(A,B) (((A) < (B)) ? (A) : (B))
  132.  
  133. #ifdef __STDC__
  134. void
  135. redraw_info (void)
  136. #else
  137. void
  138. redraw_info ()
  139. #endif
  140. {
  141.   if (!input_view.current_info)
  142.     return;
  143.   {
  144.     int ipos = input_view.info_pos;
  145.     int stop = MIN (input_view.current_info->len, scr_lines - 1 + ipos);
  146.     while (ipos < stop)
  147.       {
  148.     move (1 + ipos - input_view.info_pos, 0);
  149.     addstr (input_view.current_info->text[ipos]);
  150.     clrtoeol ();
  151.     ++ipos;
  152.       }
  153.   }
  154.   _io_redraw_input ();
  155. }
  156.  
  157.  
  158. #ifdef __STDC__
  159. static void
  160. _io_fix_input (void)
  161. #else
  162. static void
  163. _io_fix_input ()
  164. #endif
  165. {
  166.   iv_fix_input (&input_view);
  167. }
  168.  
  169. #ifdef __STDC__
  170. static void
  171. _io_move_cursor (void)
  172. #else
  173. static void
  174. _io_move_cursor ()
  175. #endif
  176. {
  177.   iv_move_cursor (&input_view);
  178. }
  179.  
  180. #ifdef __STDC__
  181. static void
  182. _io_erase (int len)
  183. #else
  184. static void
  185. _io_erase (len)
  186.      int len;
  187. #endif
  188. {
  189.   iv_erase (&input_view, len);
  190. }
  191.  
  192. #ifdef __STDC__
  193. static void
  194. _io_insert (int len)
  195. #else
  196. static void
  197. _io_insert (len)
  198.      int len;
  199. #endif
  200. {
  201.   iv_insert (&input_view, len);
  202. }
  203.        
  204. #ifdef __STDC__
  205. static void
  206. _io_over (char * str, int len)
  207. #else
  208. static void
  209. _io_over (str, len)
  210.      char * str;
  211.      int len;
  212. #endif
  213. {
  214.   iv_over (&input_view, len);
  215. }
  216.  
  217.  
  218.  
  219.  
  220.  
  221. #ifdef __STDC__
  222. static void 
  223. _io_display_cell_cursor (void)
  224. #else
  225. static void 
  226. _io_display_cell_cursor ()
  227. #endif
  228. {
  229.   int cell_cursor_row;
  230.   int cell_cursor_col;
  231.   int cc;
  232.   int rr;
  233.   int cwid;
  234.   int n;
  235.   int x, y;
  236.  
  237.   if (input_view.current_info)
  238.     return;
  239.  
  240.   if (   (curow < cwin->screen.lr)
  241.       || (cucol < cwin->screen.lc)
  242.       || (curow > cwin->screen.hr)
  243.       || (cucol > cwin->screen.hc))
  244.     return;
  245.  
  246.   getyx (stdscr, y, x);
  247.   cell_cursor_col = cwin->win_over;
  248.   for (cc = cwin->screen.lc; cc < cucol; cc++)
  249.     cell_cursor_col += get_width (cc);
  250.   cell_cursor_row = cwin->win_down;
  251.   for (rr = cwin->screen.lr; rr < curow; rr++)
  252.     cell_cursor_row += get_height (rr);
  253.   cwid = get_width (cucol);
  254.   if (cwid > cwin->numc)
  255.     cwid = cwin->numc;
  256.   move (cell_cursor_row, cell_cursor_col);
  257.   standout ();
  258.   for (n = cwid; n; n--)
  259. #ifdef A_STANDOUT
  260.     addch (inch () | A_STANDOUT);
  261. #else
  262.     addch (inch ());
  263. #endif
  264.   standend ();
  265.   move (y, x);
  266. }
  267.  
  268. #ifdef __STDC__
  269. static void 
  270. _io_hide_cell_cursor (void)
  271. #else
  272. static void 
  273. _io_hide_cell_cursor ()
  274. #endif
  275. {
  276.   int cc;
  277.   int rr;
  278.   int cell_cursor_row;
  279.   int cell_cursor_col;
  280.   int cwid;
  281.   int n;
  282.   int x, y;
  283.  
  284.   if (input_view.current_info)
  285.     return;
  286.   if (   (curow < cwin->screen.lr)
  287.       || (cucol < cwin->screen.lc)
  288.       || (curow > cwin->screen.hr)
  289.       || (cucol > cwin->screen.hc))
  290.     return;
  291.   getyx (stdscr, y, x);
  292.   cell_cursor_col = cwin->win_over;
  293.   for (cc = cwin->screen.lc; cc < cucol; cc++)
  294.     cell_cursor_col += get_width (cc);
  295.   cell_cursor_row = cwin->win_down;
  296.   for (rr = cwin->screen.lr; rr < curow; rr++)
  297.     cell_cursor_row += get_height (rr);
  298.   cwid = get_width (cucol);
  299.   if (cwid > cwin->numc)
  300.     cwid = cwin->numc;
  301.   move (cell_cursor_row, cell_cursor_col);
  302.   for (n = cwid; n; n--)
  303. #ifdef A_STANDOUT
  304.     addch (inch () & ~A_STANDOUT);
  305. #else
  306.     addch (inch ());
  307. #endif
  308.   move (y, x);
  309. }
  310.  
  311.  
  312.  
  313. /* Functions, etc for dealing with cell contents being displayed
  314.     on top of other cells. */
  315.  
  316. struct slops
  317. {
  318.   int s_alloc, s_used;
  319.   struct s
  320.     {
  321.       CELLREF row, clo, chi;
  322.     } s_b[1];
  323. };
  324.  
  325. #ifdef __STDC__
  326. static void 
  327. flush_slops (VOIDSTAR where)
  328. #else
  329. static void 
  330. flush_slops (where)
  331.      VOIDSTAR where;
  332. #endif
  333. {
  334.   struct slops *s;
  335.  
  336.   s = where;
  337.   if (s)
  338.     s->s_used = 0;
  339. }
  340.  
  341. #ifdef __STDC__
  342. static int 
  343. find_slop (VOIDSTAR where, CELLREF r, CELLREF c, CELLREF *cclp, CELLREF *cchp)
  344. #else
  345. static int 
  346. find_slop (where, r, c, cclp, cchp)
  347.      VOIDSTAR where;
  348.      CELLREF r;
  349.      CELLREF c;
  350.      CELLREF *cclp;
  351.      CELLREF *cchp;
  352. #endif
  353. {
  354.   int n;
  355.   struct slops *s;
  356.  
  357.   s = where;
  358.   if (!s)
  359.     return 0;
  360.   for (n = 0; n < s->s_used; n++)
  361.     {
  362.       if (s->s_b[n].row == r && s->s_b[n].clo <= c && s->s_b[n].chi >= c)
  363.     {
  364.       *cclp = s->s_b[n].clo;
  365.       *cchp = s->s_b[n].chi;
  366.       return 1;
  367.     }
  368.     }
  369.   return 0;
  370. }
  371.  
  372. #ifdef __STDC__
  373. static void 
  374. kill_slop (VOIDSTAR where, CELLREF r, CELLREF clo, CELLREF chi)
  375. #else
  376. static void 
  377. kill_slop (where, r, clo, chi)
  378.      VOIDSTAR where;
  379.      CELLREF r;
  380.      CELLREF clo;
  381.      CELLREF chi;
  382. #endif
  383. {
  384.   int n;
  385.   struct slops *s;
  386.  
  387.   s = where;
  388.   for (n = 0; n < s->s_used; n++)
  389.     {
  390.       if (s->s_b[n].row == r && s->s_b[n].clo == clo && s->s_b[n].chi == chi)
  391.     {
  392.       --(s->s_used);
  393.       s->s_b[n] = s->s_b[s->s_used];
  394.       return;
  395.     }
  396.     }
  397. }
  398.  
  399. #ifdef __STDC__
  400. static void 
  401. set_slop (VOIDSTAR *wherep, CELLREF r, CELLREF clo, CELLREF chi)
  402. #else
  403. static void 
  404. set_slop (wherep, r, clo, chi)
  405.      VOIDSTAR *wherep;
  406.      CELLREF r;
  407.      CELLREF clo;
  408.      CELLREF chi;
  409. #endif
  410. {
  411.   int n;
  412.   struct slops **sp;
  413.  
  414.   sp = (struct slops **) wherep;
  415.   if (!*sp)
  416.     {
  417.       (*sp) = ck_malloc (sizeof (struct slops) + 2 * sizeof (struct s));
  418.       (*sp)->s_alloc = 2;
  419.       (*sp)->s_used = 1;
  420.       n = 0;
  421.     }
  422.   else
  423.     {
  424.       n = (*sp)->s_used++;
  425.       if ((*sp)->s_alloc == n)
  426.     {
  427.       (*sp)->s_alloc = n * 2;
  428.       (*sp) = ck_realloc ((*sp), sizeof (struct slops) + n * 2 * sizeof (struct s));
  429.     }
  430.     }
  431.   (*sp)->s_b[n].row = r;
  432.   (*sp)->s_b[n].clo = clo;
  433.   (*sp)->s_b[n].chi = chi;
  434. }
  435.  
  436. #ifdef __STDC__
  437. static void 
  438. change_slop (VOIDSTAR where,
  439.          CELLREF r, CELLREF olo, CELLREF ohi, CELLREF lo, CELLREF hi)
  440. #else
  441. static void 
  442. change_slop (where, r, olo, ohi, lo, hi)
  443.      VOIDSTAR where;
  444.      CELLREF r;
  445.      CELLREF olo;
  446.      CELLREF ohi;
  447.      CELLREF lo;
  448.      CELLREF hi;
  449. #endif
  450. {
  451.   int n;
  452.   struct slops *s;
  453.  
  454.   s = where;
  455.   for (n = 0; n < s->s_used; n++)
  456.     {
  457.       if (s->s_b[n].row == r && s->s_b[n].clo == olo && s->s_b[n].chi == ohi)
  458.     {
  459.       s->s_b[n].clo = lo;
  460.       s->s_b[n].chi = hi;
  461.       return;
  462.     }
  463.     }
  464. }
  465.  
  466.  
  467. #ifdef __STDC__
  468. static void 
  469. _io_open_display (void)
  470. #else
  471. static void 
  472. _io_open_display ()
  473. #endif
  474. {
  475.   initscr ();
  476.   scrollok (stdscr, 0);
  477. #ifdef HAVE_CBREAK
  478.   cbreak ();
  479. #else
  480.   crmode ();
  481. #endif
  482.   raw ();
  483.   noecho ();
  484.   nonl ();
  485.   /* Must be after initscr() */
  486.   io_init_windows (LINES, COLS - 1, 1, 2, 1, 1, 1, 1);
  487.   info_rows = 1;
  488.   print_width = COLS;        /* Make ascii print width == terminal width. */
  489. }
  490.  
  491. #ifdef __STDC__
  492. void
  493. cont_curses(void)
  494. #else
  495. void
  496. cont_curses()
  497. #endif
  498. {
  499. #ifdef HAVE_CBREAK
  500.   cbreak ();
  501. #else
  502.   crmode ();
  503. #endif
  504.   raw ();
  505.   noecho ();
  506.   nonl ();
  507. }
  508.  
  509.  
  510. #ifdef __STDC__
  511. void
  512. stop_curses(void)
  513. #else
  514. void
  515. stop_curses()
  516. #endif
  517. {
  518. #ifdef HAVE_CBREAK
  519.   nocbreak ();
  520. #else
  521.   nocrmode ();
  522. #endif
  523.   noraw ();
  524.   echo ();
  525.   nl ();
  526.   io_redisp ();
  527. }
  528.  
  529. #ifdef __STDC__
  530. static void 
  531. _io_cellize_cursor (void)
  532. #else
  533. static void 
  534. _io_cellize_cursor ()
  535. #endif
  536. {
  537. }
  538.  
  539. #ifdef __STDC__
  540. static void 
  541. _io_inputize_cursor (void)
  542. #else
  543. static void 
  544. _io_inputize_cursor ()
  545. #endif
  546. {
  547. }
  548.  
  549. #ifdef __STDC__
  550. static void 
  551. _io_redisp (void)
  552. #else
  553. static void 
  554. _io_redisp ()
  555. #endif
  556. {
  557.   if (!term_cursor_claimed)
  558.     {
  559.       _io_redraw_input ();
  560.       if (!(input_view.current_info || input_active ||
  561.         input_view.expanded_keymap_prompt))
  562.     move_cursor_to (cwin, curow, cucol, 0);
  563.       else
  564.     move ((input_view.current_info ? 0 : input), 
  565.           input_view.prompt_wid + input_view.input_cursor -
  566.           input_view.visibility_begin); 
  567.     }
  568.   {
  569.     struct rng * rng = &cwin->screen;
  570.     if (   (curow > rng->hr)
  571.     || (curow < rng->lr)
  572.     || (cucol > rng->hc)
  573.     || (cucol < rng->lc))
  574.       io_recenter_cur_win ();
  575.   }
  576.   refresh ();
  577. }
  578.  
  579. #ifdef __STDC__
  580. static void 
  581. _io_repaint_win (struct window *win)
  582. #else
  583. static void 
  584. _io_repaint_win (win)
  585.      struct window *win;
  586. #endif
  587. {
  588.   io_repaint ();
  589. }
  590.  
  591. #ifdef __STDC__
  592. static void 
  593. _io_repaint (void)
  594. #else
  595. static void 
  596. _io_repaint ()
  597. #endif
  598. {
  599.   CELLREF cc, rr;
  600.   int n, n1;
  601.   CELL *cp;
  602.   struct window *win;
  603.  
  604.   clear ();
  605.   io_fix_input ();
  606.   redrew++;
  607.   if (input_view.current_info)
  608.     {
  609.       redraw_info ();
  610.       input_view.redraw_needed = FULL_REDRAW;
  611.       _io_redraw_input ();
  612.       return;
  613.     }
  614.  
  615.   for (win = wins; win < &wins[nwin]; win++)
  616.     {
  617.       if (win->lh_wid)
  618.     {
  619.       move (win->win_down - 1, win->win_over - win->lh_wid);
  620.       printw ("#%*d ", win->lh_wid - 2, 1 + win - wins);
  621.       if (win->flags & WIN_EDGE_REV)
  622.         standout ();
  623.       cc = win->screen.lc;
  624.       do
  625.         {
  626.           n = get_width (cc);
  627.           if (n > win->numc)
  628.         n = win->numc;
  629.           if (n > 1)
  630.         {
  631.           char *ptr;
  632.           char buf[30];
  633.  
  634.           if (a0)
  635.             ptr = col_to_str (cc);
  636.           else
  637.             {
  638.               sprintf (buf, "C%u", cc);
  639.               ptr = buf;
  640.             }
  641.           --n;
  642.           n1 = strlen (ptr);
  643.           if (n < n1)
  644.             printw ("%.*s ", n, "###############");
  645.           else
  646.             {
  647.               n1 = (n - n1) / 2;
  648.               printw ("%*s%-*s ", n1, "", n - n1, ptr);
  649.             }
  650.         }
  651.           else if (n == 1)
  652.         addstr ("#");
  653.         }
  654.       while (cc++ < win->screen.hc);
  655.  
  656.       rr = win->screen.lr;
  657.       n = win->win_down;
  658.       do
  659.         {
  660.           n1 = get_height (rr);
  661.           if (n1)
  662.         {
  663.           move (n, win->win_over - win->lh_wid);
  664.           if (a0)
  665.             printw ("%-*d ", win->lh_wid - 1, rr);
  666.           else
  667.             printw ("R%-*d", win->lh_wid - 1, rr);
  668.           n += n1;
  669.         }
  670.         }
  671.       while (rr++ < win->screen.hr);
  672.  
  673.       if (win->flags & WIN_EDGE_REV)
  674.         standend ();
  675.     }
  676.       flush_slops (win->win_slops);
  677.       find_cells_in_range (&(win->screen));
  678.       while (cp = next_row_col_in_range (&rr, &cc))
  679.     if (GET_TYP (cp))
  680.       io_pr_cell_win (win, rr, cc, cp);
  681.     }
  682.   if (!(cp = find_cell (curow, cucol)) || !GET_TYP (cp))
  683.     io_display_cell_cursor ();
  684.   input_view.redraw_needed = FULL_REDRAW;
  685.   _io_redraw_input ();
  686.   io_update_status ();
  687. }
  688.  
  689. #ifdef __STDC__
  690. static void 
  691. _io_close_display (void)
  692. #else
  693. static void 
  694. _io_close_display ()
  695. #endif
  696. {
  697.   clear ();
  698.   refresh ();
  699.   (void) endwin ();
  700. }
  701.  
  702. #ifdef __STDC__
  703. static int 
  704. _io_input_avail (void)
  705. #else
  706. static int 
  707. _io_input_avail ()
  708. #endif
  709. {
  710.   return (FD_ISSET (0, &read_pending_fd_set)
  711.       || FD_ISSET (0, &exception_pending_fd_set));
  712. }
  713.  
  714. #ifdef __STDC__
  715. static void 
  716. _io_scan_for_input (int block)
  717. #else
  718. static void 
  719. _io_scan_for_input (block)
  720.      int block;
  721. #endif
  722. {
  723.   /* This function only exists because X kbd events don't generate */
  724.   /* SIGIO. Under curses, the SIGIO hander does the work of this */
  725.   /* function. */
  726. }
  727.  
  728. #ifdef __STDC__
  729. static void 
  730. _io_wait_for_input (void)
  731. #else
  732. static void 
  733. _io_wait_for_input ()
  734. #endif
  735. {
  736.   pause ();
  737. }
  738.  
  739. #ifdef __STDC__
  740. static int 
  741. _io_read_kbd (VOLATILE char *buf, int size)
  742. #else
  743. static int 
  744. _io_read_kbd (buf, size)
  745.      VOLATILE char *buf;
  746.      int size;
  747. #endif
  748. {
  749.   int r = read (0, buf, size);
  750.   FD_CLR (0, &read_pending_fd_set);
  751.   FD_CLR (0, &exception_pending_fd_set);
  752.   return r;
  753. }
  754.  
  755.  
  756. #if defined(SIGIO)
  757.  
  758.  
  759. #ifdef __STDC__
  760. static void 
  761. _io_nodelay (int delayp)
  762. #else
  763. static void 
  764. _io_nodelay (delayp)
  765.      int delayp;
  766. #endif
  767. {
  768.   panic ("Trying to curses nodelay on a system with SIGIO.");
  769. }
  770.  
  771. #else
  772.  
  773. #ifdef __STDC__
  774. static void 
  775. _io_nodelay (int delayp)
  776. #else
  777. static void 
  778. _io_nodelay (delayp)
  779.      int delayp;
  780. #endif
  781. {
  782.   nodelay (stdscr, delayp);
  783. }
  784.  
  785. #endif
  786.  
  787. #ifdef __STDC__
  788. static int 
  789. _io_getch (void)
  790. #else
  791. static int 
  792. _io_getch ()
  793. #endif
  794. {
  795.   char ch;
  796.   return ((io_read_kbd (&ch, 1) != 1)
  797.       ? EOF
  798.       : ch);
  799. }
  800.  
  801.  
  802. #ifdef __STDC__
  803. static int 
  804. _io_get_chr (char *prompt)
  805. #else
  806. static int 
  807. _io_get_chr (prompt)
  808.      char *prompt;
  809. #endif
  810. {
  811.   int x;
  812.   mvaddstr (input, 0, prompt);
  813.   clrtoeol ();
  814.   topclear = 2;
  815.   refresh ();
  816.   ++term_cursor_claimed;
  817.   x = get_chr ();
  818.   --term_cursor_claimed;
  819.   return x;
  820. }
  821.  
  822. #define BUFFER 10
  823.  
  824. #ifdef __STDC__
  825. static void 
  826. local_putchar (int ch)
  827. #else
  828. static void 
  829. local_putchar (ch)
  830.      int ch;
  831. #endif
  832. {
  833.   (void) putc (ch, stdout);
  834.   /* (void)putchar(ch); */
  835. }
  836.  
  837. #ifdef __STDC__
  838. static void
  839. local_puts (char *s)
  840. #else
  841. static void
  842. local_puts (s)
  843.     char *s;
  844. #endif
  845. {
  846.    (void) tputs (s, 1, (int (*)()) local_putchar);
  847. }
  848.  
  849. #ifdef __STDC__
  850. static void 
  851. _io_bell (void)
  852. #else
  853. static void 
  854. _io_bell ()
  855. #endif
  856. {
  857. #ifndef HAVE_GETCAP
  858.   putchar ('\007');
  859. #else
  860.   static char *vb;
  861.   static int called = 0;
  862.  
  863.   if (!called)
  864.     {
  865.       called++;
  866.       vb = getcap ("vb");
  867.     }
  868.   if (vb)
  869.     {
  870.       local_puts (vb);
  871.     }
  872.   else
  873.     {
  874.       local_putchar ('\007');
  875.     }
  876. #endif
  877. }
  878.  
  879.  
  880. #if __STDC__
  881. static void
  882. move_cursor_to (struct window *win, CELLREF r, CELLREF c, int dn)
  883. #else
  884. static void
  885. move_cursor_to (win, r, c, dn)
  886.      struct window *win;
  887.      CELLREF r;
  888.      CELLREF c;
  889.      int dn;
  890. #endif
  891. {
  892.   int cc;
  893.   int cell_cursor_col;
  894.   int rr;
  895.   int cell_cursor_row;
  896.   
  897.   cell_cursor_col = win->win_over;
  898.   for (cc = win->screen.lc; cc < c; cc++)
  899.     cell_cursor_col += get_width (cc);
  900.   cell_cursor_row = win->win_down + dn;
  901.   for (rr = win->screen.lr; rr < r; rr++)
  902.     cell_cursor_row += get_height (rr);
  903.   move (cell_cursor_row, cell_cursor_col);
  904. }
  905.  
  906. #ifdef __STDC__
  907. static void
  908. _io_update_status (void)
  909. #else
  910. static void
  911. _io_update_status ()
  912. #endif
  913. {
  914.   CELL *cp;
  915.   char *dec;
  916.   char *ptr;
  917.   static char hmbuf[40];
  918.   int wid;
  919.   int plen;
  920.   int dlen;
  921.   int yy, xx;
  922.   
  923.   if (!user_status || input_view.current_info)
  924.     return;
  925.   getyx (stdscr, yy, xx);
  926.   move (status, 0);
  927.   wid = COLS - 2;
  928.   
  929.   if (mkrow != NON_ROW)
  930.     {
  931.       struct rng r;
  932.       
  933.       addch ('*');
  934.       --wid;
  935.       set_rng (&r, curow, cucol, mkrow, mkcol);
  936.       ptr = range_name (&r);
  937.     }
  938.   else
  939.     ptr = cell_name (curow, cucol);
  940.   
  941.   addstr (ptr);
  942.   wid -= strlen (ptr);
  943.   
  944.   if (how_many != 1)
  945.     {
  946.       sprintf (hmbuf, " {%d}", how_many);
  947.       addstr (hmbuf);
  948.       wid -= strlen (hmbuf);
  949.     }
  950.   
  951.   if ((cp = find_cell (curow, cucol)) && cp->cell_formula)
  952.     {
  953.       dec = decomp (curow, cucol, cp);
  954.       dlen = strlen (dec);
  955.     }
  956.   else
  957.     {
  958.       dec = 0;
  959.       dlen = 0;
  960.     }
  961.   
  962.   ptr = cell_value_string (curow, cucol);
  963.   plen = strlen (ptr);
  964.   
  965.   if (dec)
  966.     {
  967.       wid -= 4;
  968.       if (dlen + plen > wid)
  969.     {
  970.       if (plen + 3 > wid)
  971.         printw (" %.*s... [...]", wid - 6, ptr);
  972.       else
  973.         printw (" %s [%.*s...]", ptr, wid - plen - 3, dec);
  974.     }
  975.       else
  976.     printw (" %s [%s]", ptr, dec);
  977.       decomp_free ();
  978.     }
  979.   else if (plen)
  980.     {
  981.       --wid;
  982.       if (plen > wid)
  983.     printw (" %.*s...", wid - 3, ptr);
  984.       else
  985.     printw (" %s", ptr);
  986.     }
  987.   
  988.   clrtoeol ();
  989.   move (yy, xx);
  990. }
  991.  
  992. extern int auto_recalc;
  993.  
  994. #ifdef __STDC__
  995. static void
  996. _io_clear_input_before (void)
  997. #else
  998. static void
  999. _io_clear_input_before ()
  1000. #endif
  1001. {
  1002.   textout = 0;
  1003.   if (topclear == 2)
  1004.     {
  1005.       move (input, 0);
  1006.       clrtoeol ();
  1007.       topclear = 0;
  1008.     }
  1009.   move (0, 0);
  1010. }
  1011.  
  1012. #ifdef __STDC__
  1013. static void
  1014. _io_clear_input_after (void)
  1015. #else
  1016. static void
  1017. _io_clear_input_after ()
  1018. #endif
  1019. {
  1020.   if (topclear)
  1021.     {
  1022.       move (input, 0);
  1023.       clrtoeol ();
  1024.       topclear = 0;
  1025.     }
  1026. }
  1027.  
  1028.  
  1029. #if __STDC__
  1030. static void
  1031. _io_pr_cell_win (struct window *win, CELLREF r, CELLREF c, CELL *cp)
  1032. #else
  1033. static void
  1034. _io_pr_cell_win (win, r, c, cp)
  1035.      struct window *win;
  1036.      CELLREF r;
  1037.      CELLREF c;
  1038.      CELL *cp;
  1039. #endif
  1040. {
  1041.   int glowing;
  1042.   int lenstr;
  1043.   int j;
  1044.   int wid, wwid;
  1045.   int hgt;
  1046.   char *ptr;
  1047.   int yy, xx;
  1048.   
  1049.   if (input_view.current_info)
  1050.     return;
  1051.  
  1052.   wid = get_width (c);
  1053.   if (!wid)
  1054.     return;
  1055.   if (wid > win->numc)
  1056.     wid = win->numc;
  1057.   hgt = get_height (r);
  1058.   if (!hgt)
  1059.     return;
  1060.   if (hgt > win->numr)
  1061.     hgt = win->numr;
  1062.   
  1063.   getyx (stdscr, yy, xx);
  1064.   glowing = (r == curow && c == cucol && win == cwin);
  1065.   ptr = print_cell (cp);
  1066.   move_cursor_to (win, r, c, 0);
  1067.   if (glowing)
  1068.     standout ();
  1069.   j = GET_JST (cp);
  1070.   if (j == JST_DEF)
  1071.     j = default_jst;
  1072.   lenstr = strlen (ptr);
  1073.   
  1074.   if (lenstr <= wid - 1)
  1075.     {
  1076.       CELLREF ccl, cch;
  1077.       
  1078.       if (j == JST_LFT)
  1079.     printw ("%-*.*s", wid, wid - 1, ptr);
  1080.       else if (j == JST_RGT)
  1081.     printw ("%*.*s ", wid - 1, wid - 1, ptr);
  1082.       else if (j == JST_CNT)
  1083.     {
  1084.       wwid = (wid - 1) - lenstr;
  1085.       printw ("%*s%*s ", (wwid + 1) / 2 + lenstr, ptr, wwid / 2, "");
  1086.     }
  1087. #ifdef TEST
  1088.       else
  1089.     panic ("Unknown justification");
  1090. #endif
  1091.       if (glowing)
  1092.     standend ();
  1093.       
  1094.       if (lenstr == 0 && c > win->screen.lc
  1095.       && find_slop (win->win_slops, r, c - 1, &ccl, &cch))
  1096.     {
  1097.       CELLREF ccdl, ccdh;
  1098.       
  1099.       if (find_slop (win->win_slops, r, c, &ccdl, &ccdh) && ccdl == c)
  1100.         {
  1101.           kill_slop (win->win_slops, r, ccdl, ccdh);
  1102.           for (; ccdh != ccdl; --ccdh)
  1103.         if (ccdh != c && (wwid = get_width (ccdh)))
  1104.           {
  1105.             move_cursor_to (win, r, ccdh, 0);
  1106.             printw ("%*s", wwid, "");
  1107.           }
  1108.         }
  1109.       kill_slop (win->win_slops, r, ccl, cch);
  1110.       io_pr_cell (r, ccl, find_cell (r, ccl));
  1111.     }
  1112.       else if (find_slop (win->win_slops, r, c, &ccl, &cch))
  1113.     {
  1114.       kill_slop (win->win_slops, r, ccl, cch);
  1115.       for (; cch != ccl; --cch)
  1116.         if (cch != c && (wwid = get_width (cch)))
  1117.           {
  1118.         move_cursor_to (win, r, cch, 0);
  1119.         printw ("%*s", wwid, "");
  1120.           }
  1121.       io_pr_cell (r, ccl, find_cell (r, ccl));
  1122.     }
  1123.     }
  1124.   else
  1125.     {
  1126.       CELLREF cc = c;
  1127.       CELL *ccp;
  1128.       CELLREF ccl, cch;
  1129.       
  1130.       for (wwid = wid; lenstr > wwid - 1; wwid += get_width (cc))
  1131.     {
  1132.       if (++cc > win->screen.hc
  1133.           || ((ccp = find_cell (r, cc))
  1134.           && GET_TYP (ccp)
  1135.           && (GET_FMT (ccp) != FMT_HID
  1136.               || (GET_FMT (ccp) == FMT_DEF
  1137.               && default_fmt != FMT_HID))))
  1138.         {
  1139.           --cc;
  1140.           break;
  1141.         }
  1142.     }
  1143.       
  1144.       if (lenstr > wwid - 1)
  1145.     if (GET_TYP (cp) == TYP_FLT)
  1146.       ptr = adjust_prc (ptr, cp, wwid - 1, wid - 1, j);
  1147.     else if (GET_TYP (cp) == TYP_INT)
  1148.       ptr = (char *) numb_oflo;
  1149.       
  1150.       if (wwid == 1)
  1151.     {
  1152.       addch (' ');
  1153.       if (glowing)
  1154.         standend ();
  1155.     }
  1156.       else if (wwid == wid)
  1157.     {
  1158.       printw ("%-*.*s ", wwid - 1, wwid - 1, ptr);
  1159.       if (glowing)
  1160.         standend ();
  1161.     }
  1162.       else if (glowing)
  1163.     {
  1164.       printw ("%.*s", wid, ptr);
  1165.       standend ();
  1166.       printw ("%-*.*s ", wwid - wid - 1, wwid - wid - 1, ptr + wid);
  1167.     }
  1168.       else if (r == curow && (cucol > c && cucol <= cc))
  1169.     {
  1170.       CELLREF ctmp;
  1171.       int w_left;
  1172.       int w_here;
  1173.       
  1174.       w_left = wid;
  1175.       for (ctmp = c + 1; ctmp < cucol; ctmp++)
  1176.         w_left += get_width (ctmp);
  1177.       printw ("%.*s", w_left, ptr);
  1178.       standout ();
  1179.       w_here = get_width (cucol);
  1180.       if (wwid > w_left + w_here)
  1181.         {
  1182.           printw ("%-*.*s", w_here, w_here, ptr + w_left);
  1183.           standend ();
  1184.           printw ("%-*.*s ",
  1185.               wwid - (w_left + w_here) - 1, wwid - (w_left + w_here) - 1,
  1186.               ptr + w_left + w_here);
  1187.         }
  1188.       else
  1189.         {
  1190.           printw ("%-*.*s", w_here, w_here - 1, ptr + w_left);
  1191.           standend ();
  1192.         }
  1193.     }
  1194.       else
  1195.     printw ("%-*.*s ", wwid - 1, wwid - 1, ptr);
  1196.       
  1197.       if (find_slop (win->win_slops, r, c, &ccl, &cch))
  1198.     {
  1199.       change_slop (win->win_slops, r, ccl, cch, c, cc);
  1200.       for (; cch > cc; --cch)
  1201.         if (wwid = get_width (cch))
  1202.           {
  1203.         move_cursor_to (win, r, cch, 0);
  1204.         printw ("%*s", wwid, "");
  1205.           }
  1206.       for (cch = c - 1; cch > ccl; --cch)
  1207.         if (wwid = get_width (cch))
  1208.           {
  1209.         move_cursor_to (win, r, cch, 0);
  1210.         printw ("%*s", wwid, "");
  1211.           }
  1212.       if (ccl != c)
  1213.         io_pr_cell (r, ccl, find_cell (r, ccl));
  1214.     }
  1215.       else
  1216.     set_slop ((VOIDSTAR *) (&(win->win_slops)), r, c, cc);
  1217.     }
  1218.   if ((hgt > 1) && display_formula_mode)
  1219.     {
  1220.       move_cursor_to (win, r, c, 1);
  1221.       ptr = decomp (r, c, cp);
  1222.       printw ("%.*s ", wid - 1, ptr);
  1223.       decomp_free ();
  1224.     }
  1225.   if (glowing)
  1226.     io_update_status ();
  1227.   move (yy, xx);
  1228. }
  1229.  
  1230.  
  1231.  
  1232. #ifdef __STDC__
  1233. static void
  1234. _io_flush (void)
  1235. #else
  1236. static void
  1237. _io_flush ()
  1238. #endif
  1239. {
  1240.   refresh ();
  1241. }
  1242.  
  1243.  
  1244.  
  1245.  
  1246. #ifdef __STDC__
  1247. void
  1248. tty_graphics (void)
  1249. #else
  1250. void
  1251. tty_graphics ()
  1252. #endif
  1253. {
  1254.  
  1255.   FD_SET (0, &read_fd_set);
  1256.   FD_SET (0, &exception_fd_set);
  1257.   IO_SETUP;
  1258. }
  1259.